package com.feilong.taglib.common.navigation;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.commons.core.util.Validator;
import com.feilong.servlet.http.RequestUtil;
import com.feilong.taglib.base.AbstractCommonTag;
import com.feilong.tools.velocity.VelocityUtil;

/**
 * 飞龙面包屑标签.
 * 
 * @author 金鑫 2010-6-8 上午05:50:38
 */
public class SiteMapTag extends AbstractCommonTag{

	private static final long			serialVersionUID	= -8596553099620845748L;

	/** The Constant log. */
	private static final Logger			log					= LoggerFactory.getLogger(SiteMapTag.class);

	/** 连接符,默认>. */
	private String						connector			= ">";

	/** siteMapEntityList,用户所有可以访问的菜单url List. */
	private List<SiteMapEntity<Object>>	siteMapEntityList;

	/**
	 * 实现自定义站点地图数据提供程序的途径.
	 * 
	 * @return the object
	 */
	@Override
	protected Object writeContent(){
		if (Validator.isNotNullOrEmpty(siteMapEntityList)){
			// ConfigurationManager configurationManager = new ConfigurationManager(this.pageContext.getServletContext());
			// String xmlString = configurationManager.getSiteMapXmlPath(siteMapProvider);
			// SiteMapConfigure siteMapConfigure = new SiteMapConfigure(xmlString);
			// return siteMapConfigure.getSiteMapContent("index.jsp");
			HttpServletRequest request = getHttpServletRequest();
			log.info("request.getRequestURI():{}", request.getRequestURI());
			if (log.isDebugEnabled()){
				// UrlPathHelperUtil.showProperties(request);
			}
			// if (Validator.isNull(currentPath)){
			String currentPath = RequestUtil.getOriginatingServletPath(request);
			// }
			log.info("urlPathHelper.getLookupPathForRequest(request):{}", currentPath);

			Object allParentSiteMapEntityList = getAllParentSiteMapEntityList(currentPath, siteMapEntityList);

			Map<String, Object> contextKeyValues = new HashMap<String, Object>();
			contextKeyValues.put("siteMapEntityList", allParentSiteMapEntityList);
			contextKeyValues.put("connector", connector);
			contextKeyValues.put("request", request);
			String siteMapString = VelocityUtil.parseTemplateWithClasspathResourceLoader("velocity/sitemap.vm", contextKeyValues);

			log.debug("siteMapString is:{}", siteMapString);
			if (Validator.isNullOrEmpty(siteMapString)){
				return "";
			}
			return siteMapString;
		}
		log.warn("siteMapEntityList is null");
		return "";
	}

	/**
	 * 按照父子关系排序好的 list.
	 * 
	 * @param currentPath
	 *            the current path
	 * @param siteMapEntities
	 *            the site map entities
	 * @return the all parent site map entity list
	 */
	public <T> List<SiteMapEntity<T>> getAllParentSiteMapEntityList(String currentPath,List<SiteMapEntity<T>> siteMapEntities){
		log.info("currentPath:{}", currentPath);
		SiteMapEntity<T> siteMapEntity_in = getSiteMapEntityByPath(currentPath, siteMapEntities);
		return getAllParentSiteMapEntityList(siteMapEntity_in, siteMapEntities);
	}

	/**
	 * 按照父子关系排序好的 list.
	 * 
	 * @param siteMapEntity_in
	 *            the site map entity_in
	 * @param siteMapEntities
	 *            the site map entities
	 * @return the all parent site map entity list
	 */
	public <T> List<SiteMapEntity<T>> getAllParentSiteMapEntityList(SiteMapEntity<T> siteMapEntity_in,List<SiteMapEntity<T>> siteMapEntities){
		if (null == siteMapEntity_in){
			return null;
		}
		// 每次成一个新的
		List<SiteMapEntity<T>> allParentSiteMapEntityList = new LinkedList<SiteMapEntity<T>>();
		constructParentSiteMapEntityList(siteMapEntity_in, siteMapEntities, allParentSiteMapEntityList);
		log.info("before Collections.reverse,allParentSiteMapEntityList size:{}", allParentSiteMapEntityList.size());
		// for (SiteMapEntity sme : allParentSiteMapEntityList){
		// log.info(sme.getName());
		// }
		// 反转
		Collections.reverse(allParentSiteMapEntityList);
		// log.info("after Collections.reverse");
		// for (SiteMapEntity sme : allParentSiteMapEntityList){
		// log.info(sme.getName());
		// }
		return allParentSiteMapEntityList;
	}

	/**
	 * 通过当前的SiteMapEntity,查找到所有的父节点<br>
	 * 递归生成.
	 * 
	 * @param siteMapEntity_in
	 *            the site map entity_in
	 * @param siteMapEntities
	 *            the site map entities
	 * @param allParentSiteMapEntityList
	 *            the all parent site map entity list
	 */
	private <T> void constructParentSiteMapEntityList(
			SiteMapEntity<T> siteMapEntity_in,
			List<SiteMapEntity<T>> siteMapEntities,
			List<SiteMapEntity<T>> allParentSiteMapEntityList){
		// 加入到链式表
		allParentSiteMapEntityList.add(siteMapEntity_in);
		Object parentId = siteMapEntity_in.getParentId();

		// 标识 是否找到parent node
		SiteMapEntity<T> siteMapEntity_parent = null;
		// ****************************************************
		for (SiteMapEntity<T> loopSiteMapEntity : siteMapEntities){
			// 当前的id和传入的siteMapEntity equals
			if (loopSiteMapEntity.getId().equals(parentId)){
				log.info("loopSiteMapEntity.getId():{},siteMapEntity_in.getParentId():{}", loopSiteMapEntity.getId(), parentId);
				siteMapEntity_parent = loopSiteMapEntity;
				break;
			}
		}
		if (null != siteMapEntity_parent){
			// 递归
			constructParentSiteMapEntityList(siteMapEntity_parent, siteMapEntities, allParentSiteMapEntityList);
		}
	}

	/**
	 * 匹配路径.
	 * 
	 * @param currentPath
	 *            the current path
	 * @param siteMapEntities
	 *            the site map entities
	 * @return the site map entity by path
	 */
	public <T> SiteMapEntity<T> getSiteMapEntityByPath(String currentPath,List<SiteMapEntity<T>> siteMapEntities){
		boolean flag = false;
		SiteMapEntity<T> siteMapEntity_return = null;
		for (SiteMapEntity<T> siteMapEntity : siteMapEntities){
			if (siteMapEntity.getRequestMapping().equals(currentPath)){
				flag = true;
				siteMapEntity_return = siteMapEntity;
				break;
			}
		}
		if (!flag){
			log.warn("currentPath is :{},can't find match SiteMapEntity", currentPath);
		}
		return siteMapEntity_return;
	}

	/**
	 * Sets the 连接符.
	 * 
	 * @param connector
	 *            the new 连接符
	 */
	public void setConnector(String connector){
		this.connector = connector;
	}

	/**
	 * Sets the siteMapEntityList,用户所有可以访问的菜单url List.
	 * 
	 * @param siteMapEntityList
	 *            the new siteMapEntityList,用户所有可以访问的菜单url List
	 */
	public void setSiteMapEntityList(List<SiteMapEntity<Object>> siteMapEntityList){
		this.siteMapEntityList = siteMapEntityList;
	}

}
